/**
 * Class MandateInfoModule.
 * 
 * @author Maxime Ollagnier
 */
MandateInfoModule.inherits(Module);
function MandateInfoModule() {
	var that = this;

	this.mandate = {};
	var fOnBlur = function(obj){
		var that;
		if (Util.check(obj)){
			that = obj;
		} else {
			that = this;
		}
		that.value = that.value.toUpperCase().replaceAllInMap(String.LOCALE_CARACTER_MAP);
		that.getJQ().find('input:first').val(that.value);
		return that.validate();
	};
	
	/** Creditor Modules */
	this.inputCreditor = new InputReferrerModule({
		'id' : 'inputCreditor',
		'label' : I18n.get('mandate.creditor.label'),
		'selectableType' : UserManager.TYPE_CREDITOR,
		'mandatory' : true,
		'onSelect' : function(creditor) {
			that.setCreditor(creditor, function(){ that.buildJQ(); });
		}
	});
    this.inputFlow = new InputSelectModule({
        'id' : 'inputFlow',
        'label' : I18n.get('flow'),
        'options' : {},
        'defaultValue' : '',
        'mandatory' : true,
        'getText' : function(key, object) {
            if (Util.checkObject(object)) {
                return object.name;
            }
            return object;
        },
        'onChange' : function() {
            that.setMandateFlow(Util.check(this.value) ? this.options[this.value] : undefined);
        }
    });
    this.inputContext = new InputSelectModule({
        'id' : 'inputContext',
        'label' : I18n.get('context'),
        'options' : {},
        'defaultValue' : '',
        'mandatory' : false,
        'getText' : function(key, object) {
            if (Util.checkObject(object)) {
                return object.name;
            }
            return object;
        }
    });
	this.inputCreditorAccount = new InputSelectModule({
		'id' : 'inputCreditorAccount',
		'label' : I18n.get('creditor.account'),
		'mandatory' : true,
		'getText' : function(id, account) {
			return Util.checkStringNotEmpty(account.name) ? account.name : account.bic + ' / ' + account.iban;
		}
	});
	this.inputCreditorRefName = new InputTextModule({
		'id' : 'inputCreditorRefName',
		'label' : I18n.get('mandate.ref.creditor.name'),
		'placeholder' : I18n.get('mandate.ref.creditor.name'),
		'validationPattern' : ValidationPattern.VALID_DEFAULT,
		'validationMethod' : new ValidationMethod({
			'errorMessage' : I18n.get('mandate.ref.creditor.name.mandatory'),
			'method' : function(value) {
				return Util.checkStringNotEmpty(value) || !Util.checkStringNotEmpty(that.inputCreditorRefId.value);
			}
		}),
		'onKeyUp' : function() {
			that.inputCreditorRefId.validate();
		}
	});
	
	this.inputCreditorRefId = new InputTextModule({
		'id' : 'inputCreditorRefId',
		'label' : I18n.get('mandate.ref.creditor.id'),
		'placeholder' : I18n.get('mandate.ref.creditor.id'),
		'validationPattern' : ValidationPattern.VALID_DEFAULT,
		'validationMethod' : new ValidationMethod({
			'errorMessage' : I18n.get('mandate.ref.creditor.id.mandatory'),
			'method' : function(value) {
				return Util.checkStringNotEmpty(value) || !Util.checkStringNotEmpty(that.inputCreditorRefName.value);
			}
		}),
		'onKeyUp' : function() {
			that.inputCreditorRefName.validate();
		}
	});
	
	this.inputCreditorOptInfo = new InputTextModule({
		'id' : 'inputCreditorOptInfo',
		'label' : I18n.get('mandate.creditor.optinfo'),
		'placeholder' : I18n.get('mandate.creditor.optinfoPH'),
		'validationPattern' : ValidationPattern.VALID_OPTINFO,
		'widthClass' : 'input-opt-info'
	});
	
	/** Debtor Modules */
	this.inputDebtorName = new InputTextModule({
		'id' : 'inputDebtorName',
		'label' : I18n.get('mandate.debtor.name.label'),
		'placeholder' : I18n.get('mandate.debtor.name.label'),
		'validationPattern' : ValidationPattern.VALID_NAME,
		'validationMethod' : new ValidationMethod({
			'neededLevel' : Validation.ADVISED,
			'errorMessage' : I18n.get('mandate.debtor.name.mandatory'),
			'method' : function(value) {
				return Util.checkStringNotEmpty(value);
			}
		}),
		'onBlur' : function(){
			if (fOnBlur(this) && Util.checkStringNotEmpty(that.inputDebtorFirstName.value)){
				if (Util.checkStringEmpty(that.inputSignatoryLastName.value)){
					that.inputSignatoryLastName.setValue(that.inputDebtorName.value).buildJQ();
				}
				if (Util.checkStringEmpty(that.inputSignatoryFirstName.value)){
					that.inputSignatoryFirstName.setValue(that.inputDebtorFirstName.value).buildJQ();
				}
			}
		}
	});
	this.inputDebtorFirstName = new InputTextModule({
		'id' : 'inputDebtorFirstName',
		'label' : I18n.get('mandate.debtor.firstname.label'),
		'placeholder' : I18n.get('mandate.debtor.firstname.label'),
		'validationPattern' : ValidationPattern.VALID_NAME,
		'onBlur' : function(){
			if (fOnBlur(this) && Util.checkStringNotEmpty(that.inputDebtorFirstName.value)){
				if (Util.checkStringEmpty(that.inputSignatoryLastName.value)){
					that.inputSignatoryLastName.setValue(that.inputDebtorName.value).buildJQ();
				}
				if (Util.checkStringEmpty(that.inputSignatoryFirstName.value)){
					that.inputSignatoryFirstName.setValue(that.inputDebtorFirstName.value).buildJQ();
				}
			}
		}
	});
	InputTextModule.linkInputsForLength(this.inputDebtorName, this.inputDebtorFirstName, 38);
	this.inputDebtorSIREN = new InputTextModule({
		'id' : 'inputDebtorSIREN',
		'label' : I18n.get('mandate.debtor.siren.label'),
		'placeholder' : I18n.get('mandate.debtor.siren.label'),
		'validationPattern' : ValidationPattern.VALID_SIREN
	});
	this.inputDebtorRcs = new InputTextModule({
		'id' : 'inputDebtorRcs',
		'label' : I18n.get('mandate.debtor.rcs.label'),
		'placeholder' : I18n.get('mandate.debtor.rcs.label'),
		'validationPattern' : ValidationPattern.VALID_EXTENDED
	});
	this.inputDebtorPhone = new InputTextModule({
		'id' : 'inputDebtorPhone',
		'label' : I18n.get('mandate.debtor.phone.label'),
		'placeholder' : I18n.get('mandate.debtor.phone.label'),
		'validationPattern' : ValidationPattern.VALID_PHONE_NUMBER
	});
	this.inputDebtorEmail = new InputTextModule({
		'id' : 'inputDebtorEmail',
		'label' : I18n.get('mandate.debtor.email.label'),
		'placeholder' : I18n.get('mandate.debtor.email.label'),
		'validationPattern' : ValidationPattern.VALID_EMAIL
	});
	this.inputDebtorStreetAndNumber = new InputTextModule({
		'id' : 'inputDebtorStreetAndNumber',
		'label' : I18n.get('mandate.debtor.streetnumber.label'),
		'placeholder' : I18n.get('mandate.debtor.streetnumber.label'),
		'validationPattern' : ValidationPattern.VALID_ADDRESS,
		'advised' : true,
		'onBlur' : fOnBlur
	});
	this.inputDebtorAddressComplement = new InputTextModule({
		'id' : 'inputDebtorAddressComplement',
		'label' : I18n.get('mandate.debtor.addresscomplement.label'),
		'placeholder' : I18n.get('mandate.debtor.addresscomplement.label'),
		'validationPattern' : ValidationPattern.VALID_ADDRESS,
		'onBlur' : fOnBlur
	});
	this.inputDebtorAddressComplement2 = new InputTextModule({
		'id' : 'inputDebtorAddressComplement2',
		'label' : '',
		'placeholder' : '',
		'validationPattern' : ValidationPattern.VALID_ADDRESS,
		'onBlur' : fOnBlur
	});
	this.inputDebtorPOBoxOrLocality = new InputTextModule({
		'id' : 'inputDebtorPOBoxOrLocality',
		'label' : I18n.get('mandate.debtor.POBox.label'),
		'placeholder' : I18n.get('mandate.debtor.POBox.label'),
		'validationPattern' : ValidationPattern.VALID_ADDRESS,
		'onBlur' : fOnBlur
	});
	this.inputDebtorZipCode = new InputTextModule({
		'id' : 'inputDebtorZipCode',
		'label' : I18n.get('mandate.debtor.zipcode.label'),
		'placeholder' : I18n.get('mandate.debtor.zipcode.label'),
		'validationPattern' : ValidationPattern.VALID_ZIPCODE_FR,
		'advised' : true,
		'onBlur' : fOnBlur
	});
    // Web service available by http://www.geonames.org/
    // Registered and validated account needed (To register: http://www.geonames.org/login)
    this.inputDebtorZipCode.afterJQ = function(jQ) {
        jQ.find('input').autocomplete({
            minLength: 4,
            source: function( request, response ) {
                AjaxManager.progress(true);
                $.ajax({
                    url : 'http://api.geonames.org/postalCodeSearchJSON',
                    dataType : 'json',
                    data : {
                        postalcode : request.term,
                        country : that.inputDebtorCountry.getValue(),
                        maxRows : 10,
                        username : 'limax84'
                    }
                })
                .success(function(result) {
                    AjaxManager.progress(false);
                    if (Util.checkObject(result) && Util.checkArray(result.postalCodes)) {
                        response($.map(result.postalCodes, function(item) {
                            return item.placeName;
                        }));
                    }
                })
                .error(function() {
                    AjaxManager.progress(false);
                });
            },
            select: function(event, ui) {
                event.preventDefault();
                that.inputDebtorCity.setValue(ui.item.value.replaceAllInMap(String.LOCALE_CARACTER_MAP)).validate();
                that.inputDebtorCity.buildJQ();
            }
        });
    };
	this.inputDebtorCity = new InputTextModule({
		'id' : 'inputDebtorCity',
		'label' : I18n.get('mandate.debtor.city.label'),
		'placeholder' : I18n.get('mandate.debtor.city.label'),
		'validationPattern' : ValidationPattern.VALID_CITY,
		'advised' : true,
		'onBlur' : fOnBlur
	});
	InputTextModule.linkInputsForLength(this.inputDebtorZipCode, this.inputDebtorCity, 38);
	this.inputDebtorCountry = new InputSelectModule({
		'id' : 'inputDebtorCountry',
		'label' : I18n.get('mandate.debtor.country.label'),
		'options' : Object.sortByValue(Countries.getAll()),
        'value' : 'FR',
        'onChange'  : function(value){
        	if (this.getValue() == 'FR'){
        		that.inputDebtorZipCode.setValidationPattern(ValidationPattern.VALID_ZIPCODE_FR);
        	} else {
        		that.inputDebtorZipCode.setValidationPattern(ValidationPattern.VALID_ZIPCODE);
        	}
        	that.inputDebtorZipCode.validate();
        }
	});
	this.inputDebtorRefName = new InputTextModule({
		'id' : 'inputDebtorRefName',
		'label' : I18n.get('mandate.ref.debtor.name'),
		'placeholder' : I18n.get('mandate.ref.debtor.name'),
		'validationPattern' : ValidationPattern.VALID_DEFAULT,
		'validationMethod' : new ValidationMethod({
			'errorMessage' : I18n.get('mandate.ref.debtor.name.mandatory'),
			'method' : function(value) {
				return Util.checkStringNotEmpty(value) || !Util.checkStringNotEmpty(that.inputDebtorRefId.value);
			}
		}),
		'onKeyUp' : function() {
			that.inputDebtorRefId.validate();
		}
	});
	this.inputDebtorRefId = new InputTextModule({
		'id' : 'inputDebtorRefId',
		'label' : I18n.get('mandate.ref.debtor.id'),
		'placeholder' : I18n.get('mandate.ref.debtor.id'),
		'validationPattern' : ValidationPattern.VALID_DEFAULT,
		'validationMethod' : new ValidationMethod({
			'errorMessage' : I18n.get('mandate.ref.debtor.id.mandatory'),
			'method' : function(value) {
				return Util.checkStringNotEmpty(value) || !Util.checkStringNotEmpty(that.inputDebtorRefName.value);
			}
		}),
		'onKeyUp' : function() {
			that.inputDebtorRefName.validate();
		}
	});
	
	/** Bank account modules */
	this.inputDebtorBIC = new InputTextModule({
		'id' : 'inputDebtorBIC',
		'label' : I18n.get('mandate.bic') + '**',
		'placeholder' : I18n.get('mandate.bic'),
		'validationPattern' : ValidationPattern.VALID_BIC,
		'validationMethod' : new ValidationMethod({
			'errorMessage' : I18n.get('mandate.bic.mandatory'),
			'method' : function(value) {
				return  Util.checkStringNotEmpty(value) || (Util.check(that.mandate.id) && Util.checkBoolTrue(that.mandate.hasBic) && Util.checkStringEmpty(value) && !that.inputDebtorBIC.modified);
			}
		}),
		'onKeyUp' : function(value) {
			if (Util.checkStringEmpty(value)){
				that.inputDebtorBIC.getJQ().find('input:first').attr('placeholder', I18n.get('mandate.bic'));
			}
		}
	});
	this.inputDebtorIBAN = new InputTextModule({
		'id' : 'inputDebtorIBAN',
		'label' : I18n.get('mandate.iban') + '***',
		'placeholder' : I18n.get('mandate.iban'),
		'validationPattern' : ValidationPattern.VALID_IBAN,
		'validationMethod' : new ValidationMethod({
			'errorMessage' : I18n.get('mandate.iban.mandatory'),
			'method' : function(value) {
				return Util.checkIban(value) || (Util.check(that.mandate.id) && Util.checkBoolTrue(that.mandate.hasIban) && Util.checkStringEmpty(value) && !that.inputDebtorIBAN.modified);
			}
		}),
		'onKeyUp' : function(value) {
			if (Util.checkStringEmpty(value)){
				that.inputDebtorIBAN.getJQ().find('input:first').attr('placeholder', I18n.get('mandate.iban'));
			}
		}
	});

	/** Mandate Modules */
	this.inputSignatoryLastName = new InputTextModule({
		'id' : 'inputSignatoryLastName',
		'label' : I18n.get('mandate.signatory.lastName'),
		'placeholder' : I18n.get('mandate.signatory.lastName'),
		'validationPattern' : ValidationPattern.VALID_DEFAULT
	});
	this.inputSignatoryFirstName = new InputTextModule({
		'id' : 'inputSignatoryFirstName',
		'label' : I18n.get('mandate.signatory.firstName'),
		'placeholder' : I18n.get('mandate.signatory.firstName'),
		'validationPattern' : ValidationPattern.VALID_DEFAULT
	});
	this.inputMandatDateSignature = new InputDateModule({
		'id' : 'inputMandatDateSignature',
		'label' : I18n.get('mandate.date.signature.label'),
		'placeholder' : I18n.get('mandate.date.signature.label'),
		'maxDate' : moment(),
		'defaultEmpty' : true
	});
	this.inputMandatePlaceSignature = new InputTextModule({
		'id' : 'inputMandatePlaceSignature',
		'label' : I18n.get('mandate.place.signature.label'),
		'placeholder' : I18n.get('mandate.place.signature.label'),
		'validationPattern' : ValidationPattern.VALID_DEFAULT
	});
	this.inputMandateLanguage = new InputSelectModule({
		'id' : 'inputMandateLanguage',
		'label' : I18n.get('mandate.language'),
		'options' : []
	});
	this.inputMandateRum = new InputTextModule({
		'id' : 'inputMandateRum',
		'label' : I18n.get('mandate.rum.label') + '**',
		'placeholder' : I18n.get('mandate.rum.placeholder'),
		'validationPattern' : ValidationPattern.VALID_RUM
	});
	this.inputMandateRecurrent = new InputCheckRadioModule({
		'id' : 'inputMandateRecurrent',
		'label' : I18n.get('mandate.oneoff.label'),
		'labelTrue' : I18n.get('mandate.oneoff.labelTrue'),
		'labelFalse' : I18n.get('mandate.oneoff.labelFalse'),
		'value' : true
	});
	
	this.inputCustomProperties = new Object();
	
	this.inputAccountRib = new InputTextModule({
		'id' : 'inputAccountRib',
		'label' : I18n.get('mandate.account.rib.input.title'),
		'placeholder' : I18n.get('mandate.account.rib.input.title'),
		'validationPattern' : ValidationPattern.VALID_RIB
	});
}

MandateInfoModule.neededRoles = ['VIEW_MANDATE'];

MandateInfoModule.prototype.fillJQ = function(jQ) {
	var that = this;
	
	// Creditor
	jQ.append($('<h5>' + I18n.get('creditor') + '</h5>'));
	var jQCreditorForm = $('<div class="well cropbottom"></div>');
	jQ.append(jQCreditorForm);

	var jQCreditor = $('<div class="row-fluid"></div>');
	jQCreditorForm.append(jQCreditor);
	
	var columnLeft = $('<div class="span6"></div>');
	columnLeft.append(this.inputCreditor.buildJQ());
	columnLeft.append(this.inputCreditorAccount.buildJQ());
	var columnRight = $('<div class="span6"></div>');
    columnRight.append(this.inputFlow.buildJQ());
    columnRight.append(this.inputContext.buildJQ());
    if (Object.size(that.inputContext.options) > 0) {
        this.inputContext.show();
    } else {
        this.inputContext.hide();
    }
	jQCreditor.append(columnLeft).append(columnRight);

	jQCreditorForm.append($('<hr/>'));
	jQCreditorForm.append($('<h5>' + I18n.get('mandate.ref.creditor') + '</h5>'));
	var jQCreditorRef = $('<div class="row-fluid"></div>');
	jQCreditorForm.append(jQCreditorRef);
	
	var columnLeft = $('<div class="span6"></div>');
	columnLeft.append(this.inputCreditorRefName.buildJQ());
	var columnRight = $('<div class="span6"></div>');
	columnRight.append(this.inputCreditorRefId.buildJQ());
	jQCreditorRef.append(columnLeft).append(columnRight);
	var OptInfo = $('<div class="span12" style="clear:both;margin-left:0;"></div>');
	OptInfo.append(this.inputCreditorOptInfo.buildJQ());
	jQCreditorRef.append(OptInfo);
	
	// Debtor
	jQ.append($('<h5>' + I18n.get('debtor') + '</h5>'));
	var jQDebtorForm = $('<div class="well cropbottom"></div>');
	jQ.append(jQDebtorForm);

	var jQDebtor = $('<div class="row-fluid"></div>');
	jQDebtorForm.append(jQDebtor);
	
	var columnLeft = $('<div class="span6"></div>');
	columnLeft.append(this.inputDebtorName.buildJQ());
	columnLeft.append(this.inputDebtorFirstName.buildJQ());
	columnLeft.append(this.inputDebtorSIREN.buildJQ());
	columnLeft.append(this.inputDebtorRcs.buildJQ());
	columnLeft.append(this.inputDebtorPhone.buildJQ());
	columnLeft.append(this.inputDebtorEmail.buildJQ());
	var columnRight = $('<div class="span6"></div>');
	columnRight.append(this.inputDebtorStreetAndNumber.buildJQ());
	columnRight.append(this.inputDebtorAddressComplement.buildJQ());
	columnRight.append(this.inputDebtorAddressComplement2.buildJQ());
	columnRight.append(this.inputDebtorPOBoxOrLocality.buildJQ());
	columnRight.append(this.inputDebtorZipCode.buildJQ());
	columnRight.append(this.inputDebtorCity.buildJQ());
	columnRight.append(this.inputDebtorCountry.buildJQ());
	jQDebtor.append(columnLeft).append(columnRight);

	jQDebtorForm.append($('<hr/>'));
	jQDebtorForm.append($('<h5>' + I18n.get('mandate.ref.debtor') + '</h5>'));
	var jQDebtorRef = $('<div class="row-fluid"></div>');
	jQDebtorForm.append(jQDebtorRef);
	
	var columnLeft = $('<div class="span6"></div>');
	columnLeft.append(this.inputDebtorRefName.buildJQ());
	var columnRight = $('<div class="span6"></div>');
	columnRight.append(this.inputDebtorRefId.buildJQ());
	jQDebtorRef.append(columnLeft).append(columnRight);
	
	// Bank account
	jQ.append($('<h5 class="bicIbanTitle">' + I18n.get('mandate.debtor.bank.data') + '</h5>'));
	if (UserManager.hasRoles(['VIEW_BIC_IBAN'])) {
		jQ.find('.bicIbanTitle').append($('<i class="icon-eye-open icon"/>').click(function() {
			that.refreshBicIban();
		}));
	}
	if (!UserManager.hasRoles(['WRITE_BIC_IBAN', 'WRITE_MANDATE'])) {
		this.inputDebtorBIC.setReadonly(true);
		this.inputDebtorIBAN.setReadonly(true);
	}
	var jQDebtorAccount = $('<div class="form well cropbottom row-fluid"></div>');
	jQ.append(jQDebtorAccount);
	var columnLeft = $('<div class="span6"></div>');
	columnLeft.append(this.inputDebtorBIC.buildJQ());
	var columnRight = $('<div class="span6"></div>');
	columnRight.append(this.inputDebtorIBAN.buildJQ());
	jQDebtorAccount.append(columnLeft).append(columnRight);
	var buttonRib = $('<a href="javascript:;" style="text-decoration:underline;">' + I18n.get('mandate.account.addrib') + '</a>').click(function() { that.fillInRib(); });
	jQDebtorAccount.css('text-align', 'left');
	jQDebtorAccount.append(buttonRib);
	
	// Mandate
	jQ.append($('<h5>' + I18n.get('mandate') + '</h5>'));
	var jQMandat = $('<div class="form well cropbottom row-fluid"></div>');
	jQ.append(jQMandat);
	
	var columnLeft = $('<div class="span6"></div>');
	columnLeft.append(this.inputSignatoryLastName.buildJQ());
	columnLeft.append(this.inputMandatDateSignature.buildJQ());
	columnLeft.append(this.inputMandateLanguage.buildJQ());
	columnLeft.append(this.inputMandateRecurrent.buildJQ());
	var columnRight = $('<div class="span6"></div>');
	columnRight.append(this.inputSignatoryFirstName.buildJQ());
	columnRight.append(this.inputMandatePlaceSignature.buildJQ());
	columnRight.append(this.inputMandateRum.buildJQ());
	
	jQMandat.append(columnLeft).append(columnRight);
	
	// Optional data
	if (Object.size(that.inputCustomProperties) > 0) {
		
		jQ.append($('<h5>' + I18n.get('mandate.custom.creditor.parameters') + '</h5>'));
		var jQCustomParameters = $('<div class="form well cropbottom"></div>');
		jQ.append(jQCustomParameters);
		
		$.each(that.inputCustomProperties, function(key, inputCustomProperty) {
			var jQCustomParameter = $('<div class="row-fluid"></div>');
			jQCustomParameters.append(jQCustomParameter);
			if (Util.getClassName(inputCustomProperty) == 'InputMultipleValueTextModule') {
				jQCustomParameter.append($('<div class="span12"></div>').append(inputCustomProperty.buildJQ()));
			} else {
				jQCustomParameter.append($('<div class="span6"></div>').append(inputCustomProperty.buildJQ())).append($('<div class="span6"></div>'));
			}
		});
	}
	
	// Footer
	var jQMandatFooterMandatory = $('<div class="legend">' + I18n.get('mandate.footer.mandatory.fields') + '</div>');
	var jQMandatFooterAmendment1 = $('<div class="legend">' + I18n.get('mandate.footer.amendment1.fields') + '</div>');
	var jQMandatFooterAmendment2 = $('<div class="legend">' + I18n.get('mandate.footer.amendment2.fields') + '</div>');
	jQ.append(jQMandatFooterMandatory).append(jQMandatFooterAmendment1).append(jQMandatFooterAmendment2);
	
	// Button
	if (UserManager.hasRoles(['WRITE_MANDATE'])) {
		var buttonRow = $('<div class="btn-row"></div>');
		var buttonSave = $('<button class="mandate-save-btn">' + I18n.get('save') + '</button>').click(function() { that.submitMandate(); });
		jQ.append(buttonRow.append(buttonSave));
	}
	
	// Sets focus on first input field
	this.inputDebtorName.getJQ().find('input').focus();
	
	// Executes validation to show mandatory and advised fields
	this.validate();
};

/**
 * Loads the mandate if rum and creditorId are found in parameters
 */
MandateInfoModule.prototype.loadData = function(callback) {
	if (!this.isMandateAware()) {
		this.setMandate(null, callback);
		return;
	}
	var that = this;
	AjaxManager.getJSON('getMandate', {
		'rum' : this.parameters.mandateRum,
		'creditorId' : this.parameters.creditorId
	}, function(result) {
		if (result.success) {
			that.setMandate(result.mandate, callback);
		} else {
			PopupModule.getInstance().show({
				'title' : I18n.get('warning'),
				'content' : I18n.get('mandate.not.found'),
				'button0' : { 'text' : 'OK' }
			});
			console.warn('Mandate not found [rum=' + that.parameters.mandateRum + '; creditorId=' + that.parameters.creditorId);
			Util.getFunction(callback)();
		}
	});
};

MandateInfoModule.prototype.setMandate = function(mandate, callback) {
	this.mandate = Util.getObject(mandate);
	
	var that = this;
	this.setCreditor(this.mandate.creditor, function() {
		that.inputCreditor.setReadonly(Util.check(that.mandate.id) || !UserManager.hasRoles(['WRITE_MANDATE']));
		that.inputFlow.setReadonly((Util.check(that.mandate.id) && that.mandate.status != 'Created') || !UserManager.hasRoles(['WRITE_MANDATE']));
		that.inputCreditorRefName.setValue(that.mandate.creditorRefName);
		that.inputCreditorRefId.setValue(that.mandate.creditorRefId);
		that.inputCreditorOptInfo.setValue(that.mandate.creditorOptInfo);
		that.mandate.debtor = Util.getObject(that.mandate.debtor);
		that.inputDebtorName.setValue(that.mandate.debtor.name);
		that.inputDebtorFirstName.setValue(that.mandate.debtor.firstName);
		that.inputDebtorSIREN.setValue(that.mandate.debtor.siren);
		that.inputDebtorRcs.setValue(that.mandate.debtor.rcs);
		that.inputDebtorPhone.setValue(that.mandate.debtor.phoneNumber);
		that.inputDebtorEmail.setValue(that.mandate.debtor.emailAddress);
		that.mandate.debtor.address = Util.getObject(that.mandate.debtor.address);
		that.inputDebtorStreetAndNumber.setValue(that.mandate.debtor.address.streetInfo);
		that.inputDebtorAddressComplement.setValue(that.mandate.debtor.address.line1);
		that.inputDebtorAddressComplement2.setValue(that.mandate.debtor.address.line2);
		that.inputDebtorPOBoxOrLocality.setValue(that.mandate.debtor.address.poBoxOrLocality);
		that.inputDebtorZipCode.setValue(that.mandate.debtor.address.postalCode);
		that.inputDebtorCity.setValue(that.mandate.debtor.address.townName);
		that.inputDebtorCountry.setValue(Util.checkStringNotEmpty(that.mandate.debtor.address.countryCode) ? that.mandate.debtor.address.countryCode : 'FR');
		that.inputDebtorRefName.setValue(that.mandate.debtorRefName);
		that.inputDebtorRefId.setValue(that.mandate.debtorRefId);
		that.inputSignatoryLastName.setValue(that.mandate.signatoryLastName);
		that.inputSignatoryFirstName.setValue(that.mandate.signatoryFirstName);
		
		if(Util.check(that.mandate.signDate)) {
			that.inputMandatDateSignature.setValue(moment(that.mandate.signDate).format('L'));
		} else {
			that.inputMandatDateSignature.setValue('');
		}
		
		that.inputMandatePlaceSignature.setValue(that.mandate.signPlace);
		that.inputMandateLanguage.setValue(that.mandate.language);
		that.inputMandateRum.setReadonly(Util.check(that.mandate.id) || !UserManager.hasRoles(['WRITE_MANDATE']));
		that.inputMandateRum.setValue(that.mandate.rum);
		that.inputMandateRecurrent.setValue(that.mandate.recurrent);
		that.inputMandateRecurrent.setReadonly(Util.check(that.mandate.id) || !UserManager.hasRoles(['WRITE_MANDATE']));
		that.inputDebtorBIC.setPlaceholder(Util.check(that.mandate.id) ? '*************' : I18n.get('mandate.bic'));
		that.inputDebtorBIC.setValue('');
		that.inputDebtorIBAN.setPlaceholder(Util.check(that.mandate.id) ? '*************' : I18n.get('mandate.iban'));
		that.inputDebtorIBAN.setValue('');
		Util.getFunction(callback)();
	});
};

MandateInfoModule.prototype.setCreditor = function(creditor, callback) {
	var that = this;
	
	if (!Util.check(creditor) && UserManager.user.referrer.type == UserManager.TYPE_CREDITOR) {
		creditor = UserManager.user.referrer;
	}
	
	this.inputCreditor.setValue(creditor);
	creditor = Util.getObject(creditor);
	
	// RUM
	this.inputMandateRum.setMandatory(!Util.check(this.mandate.id) && Util.checkBoolTrue(creditor.rumProvided));
	if (!Util.check(this.mandate.id) && Util.checkBoolFalse(creditor.rumProvided)) {
		this.inputMandateRum.getJQ().hide();
	} else {
		this.inputMandateRum.getJQ().show();
	}
	
	// Languages
	var languages = {};
	if (Util.check(creditor.languages)){
		for (var i=0;i<creditor.languages.length;i++){
			languages[creditor.languages[i]] = 'NaturalLanguage.' + creditor.languages[i];
		}
	}
	this.inputMandateLanguage.setOptions(languages);
	if (Util.check(this.mandate) && Util.check(this.mandate.language)) {
		this.inputMandateLanguage.setValue(this.mandate.language).buildJQ();
	} else if (Util.checkArray(creditor.languages) && creditor.languages.contains('fr')) {
		this.inputMandateLanguage.setValue('fr').buildJQ();
	}
	
	// Accounts
	var activeAccounts = {};
	if (Util.check(creditor.accounts)) {
		$.each(creditor.accounts, function(id, account) {
			if (Util.checkBoolTrue(account.active)) {
				activeAccounts[id] = account;
			}
			if (Util.checkBoolTrue(account.byDefault)) {
				that.inputCreditorAccount.setValue(account.id);
			}
		});
	}
	if (Util.check(this.mandate) && Util.check(this.mandate.creditorAccountId) && Util.check(activeAccounts[this.mandate.creditorAccountId])) {
		this.inputCreditorAccount.setValue(this.mandate.creditorAccountId);
	}
	this.inputCreditorAccount.setOptions(activeAccounts).buildJQ();
	this.inputCreditorAccount.validate();

    // Contexts
    if (Util.check(creditor.id)) {
        AjaxManager.getJSON('getAuthorizedContexts', {
            'referrerId' : creditor.id
        }, function(result) {
            that.inputContext.setOptions(result.contexts, true);
            if (Object.size(result.contexts) > 0) {
                if (Util.checkObject(that.mandate.context)){
                    (function(obj) {
                        for(var k in obj) {
                            if(obj.hasOwnProperty(k) && obj[k].id == that.mandate.context.id) {
                                that.inputContext.setValue(that.mandate.context.id);
                            }
                        }
                    })(result.contexts);
                } else if (Object.size(result.contexts) == 1){
                    (function(obj) {
                        for(var k in obj) {
                            if(obj.hasOwnProperty(k)) {
                                that.inputContext.setValue(obj[k].id);
                            }
                        }
                        return undefined;
                    })(result.contexts);
                } else {
                    (function(obj) {
                        for(var k in obj) {
                            if(obj.hasOwnProperty(k) && obj[k].id == creditor.defaultContextId) {
                                that.inputContext.setValue(obj[k].id);
                            }
                        }
                    })(result.contexts);
                }
                that.inputContext.setMandatory(true);
                that.inputContext.buildJQ().show();
            } else {
                that.inputContext.setMandatory(false);
                that.inputContext.buildJQ().hide();
            }
        });
    }

	// Optional data
	that.inputCustomProperties = new Object();
	if (Util.check(creditor.id)) {
		AjaxManager.getJSON('getInheritedCustomProperties', {
			'referrerId' : creditor.id
		}, function(result) {
			var customProperties = $.extend({}, creditor.customProperties, result.inheritedCustomProperties);
			$.each(customProperties, function(key, customProperty) {
				var inputCustomProperty = undefined;
				if (customProperty.type == 'ALPHA_NUMERIC') {
					inputCustomProperty = new InputTextModule({
						'label' : customProperty.name,
						'placeholder' : customProperty.name,
						'validationPattern' : ValidationPattern.VALID_DEFAULT
					});
				} else if (customProperty.type == 'CHOICE_LIST') {
					inputCustomProperty = new InputSelectModule({
						'label' : customProperty.name,
						'defaultValue' : '',
						'options' : customProperty.values
					});
				} else if (customProperty.type == 'VALUE_LIST') {
					inputCustomProperty = new InputMultipleValueTextModule({
						'label' : customProperty.name,
						'placeholder' : customProperty.name,
						'validationPattern' : ValidationPattern.VALID_DEFAULT
					});
				} else {
					throw 'Custom property type [' + customProperty.type + '] is invalid';
				}
				that.inputCustomProperties[customProperty.key] = inputCustomProperty;
				inputCustomProperty.key = customProperty.key;
				inputCustomProperty.name = customProperty.name;
				if (Util.checkObject(that.mandate) && Util.checkObject(that.mandate.customProperties)) {
					$.each(that.mandate.customProperties, function(j, mandateProperty) {
						if (mandateProperty.key == customProperty.key) {
							inputCustomProperty.setValue(mandateProperty.value);
						}
					});
				}
			});
			
			// Flows
			if (Util.check(creditor.id)) {
				AjaxManager.getJSON('getAvailableMandateFlowsForUser', {
					'referrerId' : creditor.id
				}, function(result) {
					if (result.success) {
						that.inputFlow.setOptions(result.availableMandateFlowsForUser, true).buildJQ();
						if (Util.checkObject(that.mandate.mandateFlow)){
							that.setMandateFlow(that.mandate.mandateFlow, callback);
						} else if (Object.size(result.availableMandateFlowsForUser) == 1){
							that.setMandateFlow((function(obj) {
								for(var k in obj) {
									if(obj.hasOwnProperty(k)) { 
										return obj[k]; 
									}
								}
								return undefined;
							})(result.availableMandateFlowsForUser), callback);
						} else {
							that.setMandateFlow((function(obj) { 
								for(var k in obj) {
									if(obj.hasOwnProperty(k) && obj[k].defaultStatus) {
										return obj[k]; 
									}
								}
								return undefined;
							})(result.availableMandateFlowsForUser), callback);
						}
						that.inputFlow.validate();
						if (result.availableMandateFlowsSize == 0){
							PopupModule.getInstance().show({
								'title' : I18n.get('mandate.info.noFlowT'),
								'content' : I18n.get('mandate.info.noFlow'),
								'button0' : { 'text' : 'OK' }
							});
						}
					}
                    else {
                        Util.getFunction(callback)();
                    }
				});
			}
		});
	}
	else {
		that.inputFlow.setOptions({}, true);
		Util.getFunction(callback)();
	}
};

MandateInfoModule.prototype.setMandateFlow = function(mandateFlow, callback) {
	var that = this;
	
	if (Util.checkObject(mandateFlow)) {

        AjaxManager.getJSON('getMandateFlow', {
            id: mandateFlow.id
        }, function(result) {
            if (result.success) {

                // Sets the value of the flow input
                that.inputFlow.setValue(result.mandateFlow.id);
                that.inputFlow.buildJQ();

                // Non-conformity acceptance flag
                var tolerant = (!Util.checkObject(that.mandate) || !Util.checkString(that.mandate.status) || that.mandate.status == 'Created') && result.mandateFlow.createdStatus;

                // Standard SEPA conformity properties
                var sepaInputs = {
                    'DEBTOR_LASTNAME' : that.inputDebtorName,
                    'DEBTOR_ACCOUNT_BIC' : that.inputDebtorBIC,
                    'DEBTOR_ACCOUNT_IBAN' : that.inputDebtorIBAN
                };

                // All mandate properties
                var inputs = $.extend({
                    'CREDITOR_ACCOUNT' : that.inputCreditorAccount,
                    'CREDITOR_REF_NAME' : that.inputCreditorRefName,
                    'CREDITOR_REF_ID' : that.inputCreditorRefId,
                    'CREDITOR_OPT' : that.inputCreditorOptInfo,
                    'DEBTOR_LASTNAME' : that.inputDebtorName,
                    'DEBTOR_FIRSTNAME' : that.inputDebtorFirstName,
                    'DEBTOR_SIREN' : that.inputDebtorSIREN,
                    'DEBTOR_RCS' : that.inputDebtorRcs,
                    'DEBTOR_PHONE' : that.inputDebtorPhone,
                    'DEBTOR_ADDRESS_STREET_INFO' : that.inputDebtorStreetAndNumber,
                    'DEBTOR_ADDRESS_POSTAL_CODE' : that.inputDebtorZipCode,
                    'DEBTOR_ADDRESS_TOWN_NAME' : that.inputDebtorCity,
                    'DEBTOR_ADDRESS_COMPLEMENT' : that.inputDebtorAddressComplement,
                    'DEBTOR_ADDRESS_COMPLEMENT2' : that.inputDebtorAddressComplement2,
                    'DEBTOR_ADDRESS_POBOXORLOCALITY' : that.inputDebtorPOBoxOrLocality,
                    'DEBTOR_ADDRESS_COUNTRY' : that.inputDebtorCountry,
                    'DEBTOR_EMAIL' : that.inputDebtorEmail,
                    'DEBTOR_REF_NAME' : that.inputDebtorRefName,
                    'DEBTOR_REF_ID' : that.inputDebtorRefId,
                    'DEBTOR_ACCOUNT_BIC' : that.inputDebtorBIC,
                    'DEBTOR_ACCOUNT_IBAN' : that.inputDebtorIBAN,
                    'SIGNATURE_PLACE' : that.inputMandatePlaceSignature,
                    'SIGNATURE_DATE' : that.inputMandatDateSignature,
                    'SIGNATORY_LASTNAME' : that.inputSignatoryLastName,
                    'SIGNATORY_FIRSTNAME' : that.inputSignatoryFirstName,
                    'LANGUAGE' : that.inputMandateLanguage
                }, that.inputCustomProperties);

                // Mandatory properties
                that.mandatoryProperties = $.merge(result.mandateFlow.mandatoryProperties, result.mandateFlow.mandatoryCustomProperties);

                // Fixed properties
                that.fixedProperties = $.merge(result.mandateFlow.fixedProperties, result.mandateFlow.fixedCustomProperties);
                var fixFieldsStatusChangedOrder = [];
                $.each(EnumManager.mandateStatusNonUpdatableField, function(key, obj){
                    fixFieldsStatusChangedOrder.push(key);
                });

                // For each properties
                $.each(inputs, function(propertyKey, input) {

                    // Sets mandatory for conformity
                    // If it's a SEPA confomity property
                    if (Util.check(sepaInputs[propertyKey])) {
                        if (Util.checkObject(input.validationMethod)) {
                            input.validationMethod.setNeededLevel(tolerant ? Validation.ADVISED : Validation.MANDATORY);
                        } else {
                            input.setMandatory(!tolerant).setAdvised(tolerant);
                        }
                    }
                    // Otherwise
                    else {
                        input.setMandatory(false).setAdvised(false);
                        if ($.inArray(propertyKey, that.mandatoryProperties) >= 0) {
                            input.setMandatory(!tolerant).setAdvised(tolerant);
                        }
                    }

                    // Sets readonly if fixed and the mandate is already compliant, or if the user doesn't have the modification rights
                    input.setReadonly(!UserManager.hasRoles(['WRITE_MANDATE']));
                    if (UserManager.hasRoles(['WRITE_MANDATE'])) {
                        $.each(that.fixedProperties, function(index, fixedPropertyKey) {
                            if( propertyKey.indexOf(fixedPropertyKey) >= 0 &&
                                Util.check(that.mandate.id) &&
                                (fixFieldsStatusChangedOrder.indexOf(that.mandate.status) < 0 || fixFieldsStatusChangedOrder.indexOf(that.mandate.status) >= fixFieldsStatusChangedOrder.indexOf(result.mandateFlow.fixFieldsStatusChanged))) {
                                input.setReadonly(true);
                                return false;
                            }
                        });
                    }

                    input.buildJQ();
                });

                //special behavior for sign name, location date
                if (Util.checkString(that.mandate.status) && that.mandate.status == 'Valid'){
                    that.inputSignatoryLastName.setReadonly(true);
                    that.inputSignatoryFirstName.setReadonly(true);
                    that.inputMandatDateSignature.setReadonly(true);
                    that.inputMandatePlaceSignature.setReadonly(true);
                }

                // Validation
                that.validate();
            }
            Util.getFunction(callback)();
        });
	}
};

MandateInfoModule.prototype.refreshBicIban = function() {
	if (!Util.check(this.mandate.id)) {
		return;
	}
	var that = this;
	AjaxManager.getJSON('getBicIban', {
		'mandateId' : this.mandate.id
	}, function(result) {
		if (result.success) {
			var bicIban = result.bicIban.split('||');
			that.inputDebtorBIC.setValue(bicIban[0]).buildJQ();
			that.inputDebtorIBAN.setValue(bicIban[1]).buildJQ();
			if (Util.checkStringEmpty(bicIban[0])){
				that.inputDebtorBIC.setPlaceholder(I18n.get('mandate.bic')).buildJQ();
			}
			if (Util.checkStringEmpty(bicIban[1])){
				that.inputDebtorIBAN.setPlaceholder(I18n.get('mandate.iban')).buildJQ();
			}
			that.inputDebtorBIC.validate();
			that.inputDebtorIBAN.validate();
			
		}
	});
};

MandateInfoModule.prototype.isMandateAware = function() {
	return Util.checkString(this.parameters.mandateRum) && Util.checkString(this.parameters.creditorId);
};

MandateInfoModule.prototype.fillInRib = function() {
	var that = this;
	
	var inner = $('<div class="span6"></div>');
	inner.append(that.inputAccountRib.buildJQ());
	inner.append('<div style="clear:both;"></div>');
	
	PopupModule.getInstance().show({
		'title' : I18n.get('mandate.account.rib.popup.title'),
		'content' : inner,
		'button0' : {
			'text' : I18n.get('mandate.account.rib.popup.ok'),
			'callback' : function() {
				if (that.inputAccountRib.validate() && String.removeWhiteSpace(that.inputAccountRib.value).length > 0){
					AjaxManager.getJSON('convertRibToBicIban', {
						'rib' : String.removeWhiteSpace(that.inputAccountRib.value)
					}, function(result) {
						if (result.success) {
							that.inputDebtorBIC.setValue(result.bic).buildJQ();
							that.inputDebtorBIC.validate();
							that.inputDebtorIBAN.setValue(result.iban).buildJQ();
							that.inputDebtorIBAN.validate();
						}
					});
				} else {
					PopupModule.getInstance().show({
						'title' : I18n.get('mandate.account.rib.invalid.title'),
						'content' : I18n.get('mandate.account.rib.invalid.content'),
						'button0' : { 'text' : 'OK' }
					});
				}
			}
		}
	});
	
};

MandateInfoModule.prototype.validate = function() {
	var valid = this.parentMethod(Module, 'validate');
	$.each(this.inputCustomProperties, function(key, inputCustomProperty) {
		valid = inputCustomProperty.validate() && valid;
	});
	return valid;
};

MandateInfoModule.prototype.submitMandate = function() {
	if (!this.validate()) {
		PopupModule.getInstance().show({
			'title' : I18n.get('invalid.form'),
			'content' : I18n.get('invalid.form.desc'),
			'button0' : { 'text' : 'OK' }
		});
		return;
	}
	
	var parameters = {
		'creditorId' : this.inputCreditor.value.creditorId,
		'creditorAccountId' : this.inputCreditorAccount.value,
		'creditorRefName' : this.inputCreditorRefName.value,
		'creditorRefId' : this.inputCreditorRefId.value,
        'creditorOptInfo' : this.inputCreditorOptInfo.value,
        'contextId' : this.inputContext.value,
		'flowName' : Util.check(this.inputFlow.value) ? this.inputFlow.options[this.inputFlow.value].name : '',
		'debtor.lastName' : this.inputDebtorName.value,
		'debtor.firstName' : this.inputDebtorFirstName.value,
		'debtor.siren' : this.inputDebtorSIREN.value,
		'debtor.rcs' : this.inputDebtorRcs.value,
		'debtor.phoneNumber' : this.inputDebtorPhone.value,
		'debtor.email' : this.inputDebtorEmail.value,
		'debtor.street' : this.inputDebtorStreetAndNumber.value,
		'debtor.complement' : this.inputDebtorAddressComplement.value,
		'debtor.complement2' : this.inputDebtorAddressComplement2.value,
		'debtor.poBoxOrLocality' : this.inputDebtorPOBoxOrLocality.value,
		'debtor.postalCode' : this.inputDebtorZipCode.value,
		'debtor.town' : this.inputDebtorCity.value,
		'debtor.countryCode' : this.inputDebtorCountry.value,
		'debtorRefName' : this.inputDebtorRefName.value,
		'debtorRefId' : this.inputDebtorRefId.value,
		'signatoryLastName' : this.inputSignatoryLastName.value,
		'signatoryFirstName' : this.inputSignatoryFirstName.value,
		'signDate' : this.inputMandatDateSignature.value,
		'signPlace' : this.inputMandatePlaceSignature.value,
		'language' : this.inputMandateLanguage.value,
		'recurrent' : this.inputMandateRecurrent.value,
		'rum' : this.inputMandateRum.value,
		'debtor.bic' : String.removeWhiteSpace(this.inputDebtorBIC.value),
		'debtor.iban' : String.removeWhiteSpace(this.inputDebtorIBAN.value),
		'bicibanmodified' : (this.inputDebtorBIC.modified || this.inputDebtorIBAN.modified) && UserManager.hasRoles(['WRITE_BIC_IBAN'])
	};
	var index = 0;
	$.each(this.inputCustomProperties, function(key, inputCustomProperty) {
		parameters['properties[' + index + '].key'] = inputCustomProperty.key;
		parameters['properties[' + index + '].value'] = inputCustomProperty.getValue();
		index++;
	});
	
	var that = this;
	if (!Util.check(this.mandate.id)) {
		AjaxManager.getJSON('saveMandate', parameters, function(result) {
			that.handleSubmitResult(result);
		});
	} else {
		AjaxManager.getJSON('updateMandate', parameters, function(result) {
			that.handleSubmitResult(result);
		});
	}
};

MandateInfoModule.prototype.handleSubmitResult = function(result) {
	var that = this;
	if (result.success) {
		PopupModule.getInstance().show({
			'title' : I18n.get('mandate.saved'),
			'content' : I18n.get('mandate.saved.desc', false, [result.rum]),
			'button0' : {
				'text' : 'OK',
				'callback' : function() {
					NavigationManager.reload('MandatePage?mandateRum=' + encodeURIComponent(result.rum) + '&creditorId=' + that.inputCreditor.value.creditorId);
				}
			}
		});
	}
};
